Celem projektu jest przećwiczenie technik przetwarzania tekstu.
Pobrałam bazę około 40 tys. tweetów na temat nierówności na tle rasowym, głównie skupiłam się na międzynarodowym ruch walczącym o prawa osób czarnoskórych - Black Lives Matter ( BLM ).
Następnie przeanalizowałam jaką opinię mają użytkownicy twittera na ten temat.
Pobrałam wszytskie tweety przy pomocy biblioteki snscrape i utworzyłam DataFrame z nazwą użytkownika, czasem wpisu, liczbą polubień, językiem w jakim jest tweet, miejscem skąd został napisany oraz samym tweetu.
tweets_df = pd.DataFrame(attributes_container, columns=["User", "Date Created", "Number of Likes", "Lang",'Place', "Tweet"])
Po pobraniu wszytskich tweetów przefiltrowałam je i skupiłam się tylko na tweetach anglojęzycznych. Zmieniłam także ich indeksy.
tweets_df = tweets_df[tweets_df['Lang'] == 'en']
tweets_df.index = range(0,34185)
Następnie usuwamy we wszytskich tweetach zbędne liczby, interpunkcję oraz zamieniamy wielkie litery na małe.
tweets_df['Tweet'] = tweets_df['Tweet'].astype(str).str.replace('\d+', '' )
tweets_df['Tweet'] = tweets_df['Tweet'].str.lower()
for i in range(len(tweets_df['Tweet'])):
tweets_df['Tweet'][i] = tweets_df['Tweet'][i].translate(str.maketrans('', '', string.punctuation))
Kolejno przy użyciu 'SentimentIntensityAnalyzer' sprawdziłam opinię osób na wybrany przeze mnie temat i podzieliłam tweety na pozytywne(compund > 0,05), negatywne(compund < -0,05) oraz neutralne w pozostałych przypadkach.
analyzer = SentimentIntensityAnalyzer()
tweets_df['compound'] = [analyzer.polarity_scores(x)['compound'] for x in tweets_df['Tweet']]
label = []
for i in range(len(tweets_df['Tweet'])):
if tweets_df['compound'][i] < -0.05:
label.append('negative')
elif tweets_df['compound'][i] > 0.05:
label.append('positive')
else:
label.append('neutral')
tweets_df['compound'] = label
Procentowy wynik podziału w powyższy sposób zaprezentowałam na wykresie kołowym poniżej, jak widać, mniej wiecej tyle samo osób wyraża opinię pozytywną(13927 - 41 %) i negatywną(13064 - 38 %) na temat ruchu walczącego o prawa osób ciemnoskórych.
Następnie przeszłam do obróbki danych pod kątem zaprezentowania danych jako chmury tagów dla poszczególnej grupy opinii.
Przeprowadzamy lematyzacje,tokenizacje oraz usuwamy stopwords z tweetów przed utworzeniem chmur tagów.
lemmatizer = nltk.stem.WordNetLemmatizer()
w_tokenizer = TweetTokenizer()
for i in range(len(tweets_df['Tweet'])):
tweets_df['Tweet'][i] = [(lemmatizer.lemmatize(w)) for w in w_tokenizer.tokenize((tweets_df['Tweet'][i]))]
stop_words = set(stopwords.words('english'))
tweets_df['Tweet'] = tweets_df['Tweet'].apply(lambda x: [item for item in x if item not in stop_words])
Chmura tagów dla tweetów pozytywnych:
Możemy dostrzec tu słowa takie jak 'love', 'support', 'community', 'life' są to słowa pozytwyne co za tym idzie potwierdza to słuszność algorytmu/ biblioteki z której korzystaliśmy. Napotykałam też słowo 'alllivesmatter'.
Chmura tagów dla tweetów negatywnych:
W tym przypadku dostaliśmy wiele negatywnych słów. Co ciekawe znalazły się też słowa takie jak 'asian', ' trump', 'knee' - które są trochę dla mnie nieadekwatne.
Chmura tagów dla tweetów neutralnych:
Zaczynamy od wyznaczenia emocji przodującej czyli tej, która jest największą liczbą i dodajemy tą emocje jako nową kolumnę do naszego DataFrame. Wyniki zobrazowałam także na wykresie kołowym, gdzie przejrzyście widać, które emocje przodują wśród użytkowników tweetera korzystających z #blacklivesmatter oraz #BLM.
def emo(x):
all_emo_val = get_emotion(x)
key = max(zip(all_emo_val.values(),all_emo_val.keys()))[1]
return key
tweets_df['Max'] = tweets_df['Tweet'].apply(emo)
Procentowy wynik podziału tweetów na emocje zaprezentowałam na wykresie kołowym poniżej, jak widać, najwiecej osób wyraża zaskoczenie bądź jest zszkowanych tą sytuacją(12799 - 38 %) kolejną liczną grupą są osoby, które wyrażają emocje związane z lękiem/ strachem (9817 - 29 %) na temat ruchu walczącego o prawa osób ciemnoskórych, co jest dosyć zrozumiałe, gdy pojawiły się protesty i sprawa morderstwa George’a Floyda wyszła na jaw ludzie zaczęli się bać i byli zszokowani tym co się wydarzyło. Co mnie zaskoczyło to liczba tweetów nacechowanych złością jest ich niecałe 2,5%.
Następnie tworzymy pięć nowych kolumn i każda odpowiada oddzielnej emocji a ich komórki odpowiadają wynikom w skali od 0 do 1 jak dany tweet był nią nacechowany.
happy = []
sad =[]
angry = []
surprise = []
fear = []
for i in range(len(tweets_df['Tweet'])):
emocje = get_emotion(tweets_df['Tweet'][i])
emoc = (list(emocje.values()))
happy.append(emoc[0])
angry.append(emoc[1])
surprise.append(emoc[2])
sad.append(emoc[3])
fear.append(emoc[4])
tweets_df['Happy'] = happy
tweets_df['Sad'] = sad
tweets_df['Angry'] = angry
tweets_df['Surprise'] = surprise
tweets_df['Fear'] = fear
Kolejny krok to chmury tagów dla poszczególnych emocji: Chmura tagów dla emocji Happy:
Chmura tagów dla emocji Sad:
Chmura tagów dla emocji Surprise:
Chmura tagów dla emocji Angry:
Chmura tagów dla emocji Fear:
Oprócz całościowej analizy opinii zrobiłam też analizę czasową. Grupy tweetów rozbiłam na przedziały z różnych okresów czasu i zbadałam jak zmienia się opinia użytkowników Tweetera w czasie.
W przypadku paczki 'NLTK Vader' podzieliłam tweety na dwa okresy rok 2020 oraz od 2021 do teraz. Zdecydowałam się na taki podział, ponieważ w głównej mierze rozgłos międzynarodowym ruchem walczącym o prawa osób czarnoskórych - Black Lives Matter zaczął być popularny właśnie w połowie 2020 roku tuż po śmierci George’a Floyda, wtedy też zaczęły się liczne protesty i słowa wsparcia z wielu krajów dla osób ciemnoskówych. Na poniższym wykresie widać średnią opinię w czasie, jak widać jest praktycznie przez cały rok bliska zera a wręcz można powiedzieć,że na minusie.
Koljny wykres przedstawia analizę opinii tweetów od 2021 roku tutaj widzimy wzrost wraz z czasem pozytywnych odczuć co do ruchu BLM, może być to spowodowane tym, że po nagłośnieniu sprawy w 2020 roku w późniejszych latach nie jest już to aż tak popularne/ kontrowersyjne czy nowe.
Analiza czasowa dla przy pomocy paczki 'Text2Emotion' jest zestawieniem 5 emocji w czasie. Jak widać na początku najwięcej osób czuło strach jednak z czasem przerodziło się to w smutek a pod koniec w obecnej sytuacji ludzie są zdziwieni ale także lekko przestraszeni.
Po przetestowaniu dwóch paczek, mimo że każda z nich pomaga nam dowiedzieć się jaką opinię dany użytkownik miał na jakiś temat to są od siebie bardzo różne.
NLTK Vader - przy użyciu tej paczki wyniki były bardzo zróżnicowane wśród ludzi.Jednak przy głębszej analizie czasowej wyszło, że średnia opnia jest prawie cały czas na minusie ( bliska zeru ale wciąż na minusie ).
W przypadku Text2Emotion największa część - 38 % ludzi pisała tweety nacechowane strachem, obawą, lękiem. Najmniej osób wstawiło do sieci tweety nacechowane złością, agresją tylko 2%. W analizie czasowej spodziewałam się na poczatek złości potem współczucia i na koniec smutku w 2020 roku z powodu strzelanin jednak wyniki, które otrzymałam różniły się od moich założeń.